package com.demo.auth.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.demo.auth.dao.domain.User;
import com.demo.auth.dao.mapper.MenuMapper;
import com.demo.auth.dao.mapper.UserMapper;
import com.demo.auth.entity.bo.MenuBo;
import com.demo.common.constants.AuthRedisKey;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.Duration;
import java.util.List;

@Service
public class UsernamePasswordService {

    @Resource
    private UserMapper userMapper;
    @Resource
    private MenuMapper menuMapper;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private TokenStoreService tokenStoreService;

    private final Duration timeout = Duration.ofMinutes(60);

    public void storeInfoToCache(User user, OAuth2AccessToken accessToken) {
        Long userId = user.getId();
        List<Long> roleIds = userMapper.getRoleIdByUserId(userId);
        tokenStoreService.setAdminToken(user.getId().toString(), accessToken);
        setRole(user.getId().toString(), roleIds);
        setMemu(roleIds);
    }

    public void logout(String userId) {
        stringRedisTemplate.delete(AuthRedisKey.usernamePasswordTokenKey(userId));
    }

    private void setRole(String userId, List<Long> roleIds) {
        String key = "service-auth:role:" + userId;
        stringRedisTemplate.opsForValue().set(key, JSON.toJSONString(roleIds), timeout);
    }

    private void setMemu(List<Long> roleIds) {
        for (Long roleId : roleIds) {
            String key = AuthRedisKey.usernamePasswordMenuKey(roleId);
            String json = stringRedisTemplate.opsForValue().get(key);
            if (StringUtils.isNotBlank(json)) {
                // 重新设置有效期
                stringRedisTemplate.opsForValue().set(key, json, timeout);
                continue;
            }

            List<MenuBo> menuBos = menuMapper.queryMenuByRoleId(roleId);
            if (CollectionUtils.isEmpty(menuBos)) {
                continue;
            }

            // 设置菜单有效期
            stringRedisTemplate.opsForValue().set(key, JSON.toJSONString(menuBos), timeout);
        }
    }
}
